package com.sise.service;


import com.sise.dto.RpcRespDTO;
import com.sise.dto.TextDetectionDTO;
import com.sise.model.StringItem;
import com.sise.model.StringWordNode;
import io.netty.util.internal.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;

import static com.sise.model.StringItem.countHash;


/**
 * @author idea
 * @data 2019/6/5
 */
@Service(value = "stringWordFilter")
public class StringWordFilterImpl implements FilterService {

    @Autowired
    private TextDetectionService textDetectionService;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    private static final int DEFAULT_LENGTH = 131072;

    /**
     * 敏感指标参数
     */
    private int sensitiveLevel=0;



    private static final StringWordNode[] STRING_WORD_NODES = new StringWordNode[DEFAULT_LENGTH];


    public static boolean put(String word) {
        if (word == null || word.length() <= 2) {
            return false;
        }
        StringItem item = new StringItem(word);
        String key = word.substring(0, 2);
        int hash = countHash(key);
        //拿到桶数组的index指标
        int index = hash & (STRING_WORD_NODES.length - 1);
        int prefixHash = item.countTwoCharHash(0);
        StringWordNode node = new StringWordNode(prefixHash);

        StringWordNode bucketItem = STRING_WORD_NODES[index];
        synchronized (StringWordFilterImpl.class) {
            if (bucketItem != null) {
                for (; bucketItem != null; bucketItem = bucketItem.next) {
                    if (bucketItem.headCharMix == prefixHash) {
                        bucketItem.treeSet.add(item);
                        return true;
                    }
                    if (bucketItem.next == null) {
                        new StringWordNode(prefixHash, bucketItem).treeSet.add(item);
                        return true;
                    }
                }
            } else {
                node.treeSet.add(item);
                STRING_WORD_NODES[index] = node;
            }
        }
        return true;
    }

    @Override
    public RpcRespDTO<String> filter(String word) {
        if(StringUtil.isNullOrEmpty(word)){
            return new RpcRespDTO<String>().buildErrorParamResp(null);
        }
        StringItem stringItem = new StringItem(word);
        int length = stringItem.length();
        int index = 0;
        int step = 1;
        boolean isSensitive=false;
        List<String> wordList=new ArrayList<>();
        while (index < length - 1) {
            //查询词汇
            String matchWord = word.substring(index, index + 2);
            int hash = countHash(matchWord);
            int arrIndex = hash & (STRING_WORD_NODES.length - 1);
            StringWordNode node = STRING_WORD_NODES[arrIndex];
            //匹配到位的节点
            if (node != null) {
                int prefixHash = stringItem.countTwoCharHash(index);

                for (; node != null; node = node.next) {
                    if (node.headCharMix == prefixHash) {
                        //这里已经出现敏感词命中的情况了(这里的长度不会很长)
                        TreeSet<StringItem> treeSet = node.treeSet;

                        NavigableSet<StringItem> desSet = treeSet.descendingSet();
                        for (StringItem item : desSet) {
                            if (item.getWord().contains(matchWord)) {
                                System.out.println("出现不合理词汇！:" + matchWord);
                                sensitiveLevel++;
                                isSensitive=true;
                                wordList.add(matchWord);
                            }
                        }

                    }
                }
            }
            //匹配的步长
            index = index + step;
        }
        if(isSensitive){
            TextDetectionDTO textDetectionDTO=new TextDetectionDTO();
            textDetectionDTO.setCheckContent(word);
            textDetectionDTO.setSensitiveLevel(sensitiveLevel);
            textDetectionDTO.setSensitiveWordArr(buildSensitiveWordArr(wordList));
            textDetectionService.saveOne(textDetectionDTO);
        }
        return new RpcRespDTO<String>().buildSuccessResp(word);
    }


    public String buildSensitiveWordArr(List<String> wordList){
        if(CollectionUtils.isEmpty(wordList)){
            return StringUtil.EMPTY_STRING;
        }else{
            if(wordList.size()==1){
                return wordList.get(0);
            }else{
                StringBuilder stb=new StringBuilder();
                int index=0;
                for (String word : wordList) {
                    if(index==wordList.size()){
                        stb = stb.append(word );
                    }else {
                        stb = stb.append(word + ",");
                    }
                    index++;
                }
                return stb.toString();
            }
        }
    }
}
